package com.caesar.string;

import org.junit.jupiter.api.Test;

import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

/**
 * @author caesar
 * @date 2025/7/15
 * @Description:
 * @apiNote
 */
public class TestStringMethod {
    @Test
    public void test1(){
        String str = "hello中";
        System.out.println("字符的个数或字符串长度：" + str.length());//6
        //与字符串底层占的字节数无关。单纯的数字符的个数
        System.out.println("取[下标]位置的字符：" + str.charAt(5));//中
        //无论底层是byte[]，还是char[]，以及1个字符占几个字节，它的这个下标是从第几个字符的角度来说，从0开始
        System.out.println(str.indexOf('l'));//2   indexOf找xx的下标
        System.out.println(str.lastIndexOf('l'));//3  lastIndexOf找xx的末次下标
        System.out.println(str.contains("wo"));//false   contains是否包含
        System.out.println(str.contains("he"));//true
    }

    @Test
    public void test2(){
        String str = "  ";
        System.out.println("是否为空？" + str.isEmpty());//false
        System.out.println("是否为空？" + str.isBlank());//true

        String str2 = "";
        System.out.println("是否为空？" + str2.isEmpty());//true
        System.out.println("是否为空？" + str2.isBlank());//true
        /*
        isEmpty()，不包含任何字符
        isBlank()，除了空白字符，不包含其他字符。空白字符有空格、\t、\n等
         */
    }

    @Test
    public void test3(){
        String str = "Hello中";
        System.out.println("转大写：" + str.toUpperCase());
        System.out.println("转小写：" + str.toLowerCase());
        /*
        转大写：HELLO中
        转小写：hello中
         */
    }

    @Test
    public void test4(){
        String str = "Hello.java";
        //这个字符串是否以.java结尾
        System.out.println("是否以.java结尾：" + str.endsWith(".java"));
        String name = "张三";
        //这个字符串是不是以张开头
        System.out.println("是不是以张开头:" + str.startsWith("张") );
    }

    @Test
    public void test5(){
        String filename = "Hello.java";
        //截取上述文件名中的 后缀名
        int index = filename.lastIndexOf(".");
        String ext = filename.substring(index);//从[index]开始截取到最后
        System.out.println(ext);

        //截取上述文件名中的 除去后缀名之外部分，例如：Hello
        String name = filename.substring(0, index);//截取[0, index)部分
        System.out.println(name);
    }

    @Test
    public void test6(){
        //模拟登录：  假设数据库中的用户名是 atguigu，密码是 123456，验证码：tAb8
        Scanner input = new Scanner(System.in);

        System.out.print("请输入验证码：");
        String code = input.next();

        /*
        解决验证码不区分大小写比较问题的思路有2种：
        （1）if(code.toLowerCase().equals("tAb8".toLowerCase()))
        (2) 调用字符串的 equalsIgnoreCase 方法，忽略大小写比较字符串内容
         */
        if(code.equalsIgnoreCase("tAb8")){
            System.out.println("验证码正确");
        }else{
            System.out.println("验证码不正确");
            return;
        }

        System.out.print("请输入用户名：");
        String username = input.next();

        System.out.print("请输入密码：");
        String password = input.next();

        //input.next()得到的字符串，不是用""直接得到的字符串，因此它们不是字符串常量，不能共享，所以不能用==比较
        /*if(username == "atguigu" && password == "123456"){
            System.out.println("登录成功");
        }else{
            System.out.println("登录失败");
        }*/

        //String已经重写了Object类的方法，我们直接用，它重写为比较字符串的内容，而不是地址
        //equals是区分大小写
        if(username.equals("atguigu") && password.equals("123456")){
            System.out.println("登录成功");
        }else{
            System.out.println("登录失败");
        }

        input.close();
    }

    @Test
    public void test7(){
        String s1 = "hello";
        String s2 = "world";
//        System.out.println(s1 > s2);//错误。 s1,s2是对象，s1和s2是地址值，是无法直接用运算符比较大小的

        int result = s1.compareTo(s2);//因为String类实现了Comparable接口，重写了compareTo方法
        System.out.println(result);//-15  负整数代表 s1小于s2
    }

    @Test
    public void test8(){
        String s1 = "hello";
        String s2 = "Hello";
        int result = s1.compareTo(s2);//因为String类实现了Comparable接口，重写了compareTo方法 区分大小写
        System.out.println(result);//32  正整数代表 s1大于s2
    }

    @Test
    public void test9(){
        String[] strings = {"hello","java","chai","Hi","Tom"};
        //自然排序
        Arrays.sort(strings);  //依赖于String类实现 Comparable接口，重写了compareTo方法 区分大小写
        System.out.println(Arrays.toString(strings));
        //[Hi, Tom, chai, hello, java]
    }

    @Test
    public void test10(){
        String[] strings = {"hello","java","chai","Hi","Tom"};
        //定制排序  找Comparator接口
        Comparator c = new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                String s1 = (String) o1;
                String s2 = (String) o2;
                return s1.compareToIgnoreCase(s2);//忽略大小写比较字符串大小
            }
        };

        Arrays.sort(strings, c);
        System.out.println(Arrays.toString(strings));
        //[chai, hello, Hi, java, Tom]
    }

    @Test
    public void test11(){
        String str = "  he   llo   ";
        str = str.trim();
        System.out.println("[" + str +"]");
    }
    /*
    * 消除字符串前后的空格，如果字符串中间存在空格，无法消除，仍然保留
    * */

    @Test
    public void test12(){
        String str1 = "hello";
        String str2 = str1.trim();//因为"hello"前后没有空白字符，所以字符串不需要处理，会返回原字符串对象的地址
        System.out.println(str1 == str2);//true
    }

    @Test
    public void test13(){
        String str1 = "hello ";
        String str2 = str1.trim();//因为"hello"前后有空白字符，需要处理，就会返回新字符串对象
        System.out.println(str1 == str2);//false
    }

    @Test
    public void test14(){
        char[] arr = {'h', 'e', 'l', 'l', 'o','w','o'};
        //可以根据char[]构建字符串
        String str = new String(arr);
        String str2 = String.valueOf(arr);
        System.out.println(str);
        System.out.println(str2);

        String str3 = new String(arr, 1,4);
        String str4 = String.valueOf(arr, 1,4);
        System.out.println(str3);
        System.out.println(str4);
    }
    /*
    * String.valueOf用于将基本数据类型或对象转换为 String 类型的静态方法
    * */

    @Test
    public void test15(){
        String str = "hello";
        char[] arr = str.toCharArray();
        System.out.println(str);
        System.out.println(arr);//char[]比较特殊，直接输出，会打印出数组内容，而不是地址值
    }

    @Test
    public void test16(){
        String str = "abcd";
        byte[] bytes = str.getBytes();//按照当前运行环境的编码来对字符串进行编码
        System.out.println(Arrays.toString(bytes));//[97, 98, 99, 100]
    }

    @Test
    public void test17(){
        String str = "abcd中";
        byte[] bytes = str.getBytes();//按照当前运行环境的编码来对字符串进行编码
        System.out.println(Arrays.toString(bytes));//[97, 98, 99, 100, -28, -72, -83]
        //默认咱们的idea编码设置的是UTF-8，那么在UTF-8编码一个中文字符占3个字节
    }

    @Test
    public void test18(){
        String str = "abcd中";
        byte[] bytes = str.getBytes(Charset.forName("GBK"));//加密的过程
        System.out.println(Arrays.toString(bytes));//[97, 98, 99, 100, -42, -48]
        //在GBK编码规则中，一个汉字占2个字节
        /*
        比喻：编码方式或编码表相当于对情报加密的密码本
        同一个情报，用不同的密码本加密得到的密文是不同的。
        加密的密码本和解码的密码本必须相同，才能解密，否则会乱码
         */
    }

    @Test
    public void test19(){
        byte[] bytes = {97, 98, 99, 100, -42, -48};
        String str = new String(bytes); //解密  默认是UTF-8(因为IDEA的编码是UTF-8)
        System.out.println(str);//abcd�� 乱码
    }

    @Test
    public void test20(){
        byte[] bytes = {97, 98, 99, 100, -42, -48};
        String str = new String(bytes, Charset.forName("GBK")); //解密  指定GBK
        System.out.println(str);//abcd中
    }

    @Test
    public void test21(){
        String s1 = "hello";
        s1 = s1 + "world";//拼接

        s1 = s1.concat("java");//拼接
        System.out.println(s1);
    }
}
